home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Libraries / PatchLib 1.0d3 / Source / PatchLib / PatchLib.h < prev   
Encoding:
C/C++ Source or Header  |  1994-11-30  |  3.7 KB  |  111 lines  |  [TEXT/KAHL]

  1. /* See the file Distribution for distribution terms.
  2.     (c) Copyright 1994 Ari Halberstadt */
  3.  
  4. #pragma once
  5. #ifndef PATCH_LIB
  6. #define PATCH_LIB
  7.  
  8. #include <MixedMode.h>
  9. #include <OSUtils.h>
  10.  
  11. typedef struct PatchStructure PatchStructure;
  12. typedef struct PatchStructure *PatchType;
  13. typedef const PatchStructure *PatchCType;
  14.  
  15. /*    Data needed by a patch. The 'trap' member should be the first
  16.     member of the structure. If you move the 'trap' member, then
  17.     you must modify the _patch_return inline function (defined
  18.     later in this file).  */
  19. struct PatchStructure {
  20.     UniversalProcPtr    trap;            /* saved trap address */
  21.     UniversalProcPtr    addr;            /* address of patch routine */
  22.     PatchType            next;            /* next patch */
  23.     TrapType                type;            /* type of trap */
  24.     short                    number;        /* trap number */
  25.     Boolean                installed;    /* true if patch is installed */
  26. };
  27.  
  28. /*    µThe PATCH_ENTER macro should be the first executable statement in
  29.     your patch routine.
  30.  
  31.     For M68K patches, the PATCH_ENTER macro saves all of the registers
  32.     and sets up register a5. PATCH_ENTER also ensures that the routine\
  33.     has a stack frame so that the PATCH_RETURN macro can be used.
  34.  
  35.     For PPC patches, the PATCH_ENTER macro is currently a no-op. You
  36.     don't have to do anything special on entry to a PPC patch. However,
  37.     you should still include the PATCH_ENTER macro, for compatability
  38.     with M68K versions of your code. */
  39.  
  40. /*    µThe PATCH_RETURN macro should be the last executable statement
  41.     in your patch routine.
  42.  
  43.     For M68K patches, the PATCH_RETURN macro jumps to the address of the
  44.     originally patched routine. The 'patch' parameter should be a pointer
  45.     returned from PatchBegin.
  46.  
  47.     For PPC patches, the PATCH_RETURN macro is currently a no-op. You must
  48.     use either CallUniversalProc or CallOSTrapUniversalProc to call the
  49.     original patched routine. You should call one of these functions before
  50.     the macro PATCH_RETURN, which you should still include in your patches
  51.     for compatability with M68K versions of your code. */
  52.  
  53. #if USESROUTINEDESCRIPTORS
  54.  
  55.     #define PATCH_ENTER()            ((void) 0)
  56.     #define PATCH_RETURN(patch)    ((void) 0)
  57.  
  58. #else /* USESROUTINEDESCRIPTORS */
  59.  
  60.     /* WS_INLINE_M68K */
  61.  
  62.     // _patch_enter expands to the following M68K assembly instructions:
  63.     // movem.l a0-a5/d0-d7, -(sp)                    /* save registers */
  64.     // movea.l #0x0904, a5                            /* setup register a5 */
  65.     // movea.l (a5), a5
  66.     extern void _patch_enter(void)
  67.         SIXWORDINLINE(
  68.             0x48E7, 0xFFFC,            
  69.             0x2A7C, 0x0000, 0x0904, 
  70.             0x2A55);                
  71.     
  72.     // _patch_return expands to the following M68K assembly instructions:
  73.     // movea.l patch, a0                                /* get pointer to patch structure */
  74.     // movea.l a6, a1                                    /* get current value of a6 */
  75.     // move.l (a6), -(a6)                            /* shift location of saved a6 */
  76.     // move.l PatchStructure.trap(a0), (a1)     /* put patched routine's address on stack */
  77.     // movem.l (sp)+, a0-a5/d0-d7                    /* restore registers */
  78.     // unlk a6                                            /* pop stack frame */
  79.     // rts                                                /* return to patched routine */
  80.     #pragma parameter _patch_return(__A0)
  81.     extern void _patch_return(PatchType patch)
  82.         EIGHTWORDINLINE(
  83.             0x224E,                         
  84.             0x2D16,                        
  85.             0x22A8, 0x0000,            
  86.             0x4CDF, 0x3FFF,            
  87.             0x4E5E,                        
  88.             0x4E75);                    
  89.         
  90.     #define PATCH_ENTER() \
  91.         {    volatile long _patch_stack_frame;    /* force stack frame of at least 4 bytes */ \
  92.             _patch_enter();                            /* initialize patch */ \
  93.             _patch_stack_frame = 0;                    /* so stack frame isn't optimized out */ \
  94.             {
  95.             
  96.     #define PATCH_RETURN(patch) \
  97.                 } \
  98.                 _patch_return(patch); \
  99.             }
  100.  
  101. #endif /* USESROUTINEDESCRIPTORS */
  102.  
  103. void PatchInstall(PatchType patch);
  104. void PatchRemove(PatchType patch);
  105. void PatchRemoveAll(void);
  106. PatchType PatchBegin(UniversalProcPtr addr, short number);
  107. void PatchEnd(PatchType patch);
  108. void PatchEndAll(void);
  109.  
  110. #endif /* PATCH_LIB */
  111.